<template>
  <div>

    <h5>Count 组件</h5>
    <p>count的值是 : {{ count }}</p>
    <button ref="addRef" @click="add">+1</button>
    <button @click="show">打印 this</button>
    <button v-if="retryBtnFlag" @click="retryCount">重置</button>
  </div>
</template>

<script>
export default {
  /**
   * 声明组件的时候提供的名称, 会在Vue调试工具上显示这个组件名称
   * 当提供了 name 属性之后, 组件的名称, 就是 name 属性的值
   * 建议name属性一定要有, 并且这个属性值和文件名称一样
   * #
   * 对比
   * 1.组件的"注册名称"[App.vue组件使用了Count.vue组件, 导入这个组件的时候起来个名称]
   *  import Count from '@/components/Count'; Vue.component('MyCount', Count) | MyCount就是注册名称
   *  组件的"注册名称"主要应用场景: 以标签的形式, 把注册的组件, 渲染和使用到页面结构之中
   * #
   * 2.组件声明时候"name"名称[name: 'Count']的主要应用场景: 结合<keep-alive>标签实现组件缓存功能
   *  以及在调试工具中看到组件的 name 名称
   *
   */
  name: 'Count',

  // <div class="count" id="app" data-index="1">
  //      class id 都是标签div自带的属性, data-index 是自定义属性
  // props 是组件的自定义属性, 允许 组件使用者 通过自定义属性, 为当前组件指定初始值
  // 自定义属性的名字, 就是封装者自定义 (只要名字合法即可)
  // props中的数据, 可以直接在模板结构[ 大胡子{{}} ]中使用
  // 注意: props是只读的, 不要直接修改props值, 否则终端会报错!
  //       要想修改props的值, 可以把props的值转存到data中, 以为data中数据是可读可写的!
  //       数组形式的props不能指定默认值
  // props: ['init'],

  //      对象形式的props可以通过default来定义属性的默认值
  props: {
    init: {
      // 用 default 属性定义属性的默认值
      // 如果外界使用 Count组件的时候, 没有传递init属性, 则默认值生效
      default: 0,
      // 规则了 init 的值类型必须是 Number 数字, 不然就会报错
      // 假如传递的是的字符串127 <Count init="127">, 会出现以下错误
      // [Vue warn]: Invalid prop: type check failed for prop "init".
      // Expected Number with value 127, got String with value "127".
      type: Number,
      // 必填项校验, 它会检测使用组件时, 有没有填写, 不会看default属性,
      // 也就是说 required: true, 会导致default属性失效
      // 没有传值 <Count>, 将报错[Vue warn]: Missing required prop: "init"
      required: true
    },
    /**
     * 重置按钮是否出现flag
     */
    retryBtnFlag: {
      default: false,
      type: Boolean
    },
    obj: {
      type: Object,
      default: () => {
      }
    }
  },
  // 组件的私有数据
  data () {
    return {
      count: this.init,    // 把this.init的值转存到count,
      flag: false,
    }
  },
  created () {
    console.log(`Count 组件被创建了 count: ${this.count} - ${typeof this.count}`)
  },
  destroyed () {
    console.log(`Count 组件被销毁了`)
  },
  updated () {
    console.log(`Count 组件又出现了, 你打我啊^-^`)
  },
  /**
   * 当组件被缓存时, 会自动触发组件的 deactivated 声明周期函数
   */
  deactivated () {
    console.log('组件被缓存了, deactivated')
  },
  /**
   * 当组件被激活时, 会自动触发组件的 activated 声明周期函数
   * #
   * 注意: 当组件第一次被创建的时候, 既会触发 created 生命周期函数, 也会执行 activated 生命周期函数,
   * 并且 created 方法在 activated 的前面, 并且 created 方法在 activated 的前面
   * 当组件被激活的时候, 只会触发 activated 生命周期函数, 不会触发 created, 因为组件没有被重新创建
   */
  activated () {
    console.log('组件被激活了, activated')
  },
  computed: {

    /*addComputed () {
      // this.count++
      // 计算属性必须要有 return
      // eslint-disable-next-line vue/no-side-effects-in-computed-properties
      return this.init++
    }*/
  },
  methods: {
    add () {
      this.count += 1
      // ++会带有隐式转换, 例如 this.count = '127' 是一个string类型,
      // 但是用 ++运算符, 会将这个string类型转换为number类型
      // 经测试, 组件使用者<Count init="a">, 传递的是字符串"a", 然后使用++, 最终count变成NAN
      // this.count++
    },
    show () {
      // this对象里面, 有init和count属性,
      console.log(this)
      console.log(this.$refs.addRef)
      this.flag = !this.flag
      if (this.flag) {
        this.$refs.addRef.className = 'bgc-pink'
      } else {
        this.$refs.addRef.className = ''
      }
    },
    retryCount () {
      this.count = 0
    }
  }

}
</script>

<style lang="less">
button {
  height: 22px;
  vertical-align: bottom;
}

.bgc-pink {
  background-color: pink;
}
</style>
